

// 算法2
// min max
let alg_2 = {

    Role:{
        User:1,
        AI:2,
    },

    // 评分来自 https://kimlongli.github.io/2016/12/14/如何设计一个还可以的五子棋AI/
    ai_patterns: [
        {key: /22222/, value: 50000},
        {key: /022220/, value: 4320},
        {key: /022200/, value: 720},
        {key: /002220/, value: 720},
        {key: /022020/, value: 720},
        {key: /020220/, value: 720},
        {key: /22220/, value: 720},
        {key: /02222/, value: 720},
        {key: /22022/, value: 720},
        {key: /20222/, value: 720},
        {key: /22202/, value: 720},
        {key: /002200/, value: 120},
        {key: /002020/, value: 120},
        {key: /020200/, value: 120},
        {key: /000200/, value: 20},
        {key: /002000/, value: 20},
    ],

    user_patterns: [
        {key: /11111/, value: 50000},
        {key: /011110/, value: 4320},
        {key: /011100/, value: 720},
        {key: /001110/, value: 720},
        {key: /011010/, value: 720},
        {key: /010110/, value: 720},
        {key: /11110/, value: 720},
        {key: /01111/, value: 720},
        {key: /11011/, value: 720},
        {key: /10111/, value: 720},
        {key: /11101/, value: 720},
        {key: /001100/, value: 120},
        {key: /001010/, value: 120},
        {key: /010100/, value: 120},
        {key: /000100/, value: 20},
        {key: /001000/, value: 20},
    ],

    /**
     * 对整个盘面进行评分
     * @param board
     */
    ai_choose(board,depth) {

        // 直接对整个盘面分析
        let cells = board.cells;
        let best = -Infinity;
        let dstCell;

        cells.forEach(row=>{
            row.forEach(cell=>{
                if(cell.value !== 0){
                    return;
                }

                cell.value = 2;

                // 在这个盘面下,继续搜索下去. 直到达到目标
                let value = this.max(board,depth - 1);
                if(value > best){
                    best = value;
                    dstCell = cell;
                }
                cell.value = 0;
            })
        });
        return dstCell;
    },

    max(board,depth){
        if(depth < 1){
            return this.evaluate(this.ai_patterns,board);
        }

        //
        let best = Infinity;
        let cells  = board.cells;
        cells.forEach(row=>{
            row.forEach(cell=>{
                if(cell.value !== 0){
                    return;
                }

                cell.value = 1;
                let value = this.min(board,depth - 1);
                if(value < best){
                    best = value;
                }
                cell.value = 0;
            })
        });
        return  best;
    },

    min(board,depth){
        if(depth < 1){
            return this.evaluate(this.ai_patterns,board);
        }
        let best = -Infinity;
        let cells = board.cells;
        cells.forEach(row=>{
            row.forEach(cell=>{
                if(cell.value !== 0){
                    return;
                }
                cell.value = 2;
                let value = this.max(board,depth - 1);
                if(value > best){
                    best = value;
                }
                cell.value = 0;
            })
        });
        return  best;
    },




    // step(board,depth,aiOrUser){  // 2 为 ai , 1 为user
    //     let emptyCells = board.emptyCells();
    //     if(emptyCells.length < 0){
    //         console.log('没有位置,可能是平局或者错误!');
    //         return;
    //     }
    //
    //     // 如果 aiOrUser 为User,则取其最小值
    //     //      aiOrUser 为AI,则取其最大值
    //     if(aiOrUser === this.Role.User){
    //         // 取 最小值
    //         if(depth < 1){
    //             return this.evaluate(this.user_patterns,board);
    //         }
    //         let best = Infinity;
    //         emptyCells.forEach(cell=>{
    //             cell.value = aiOrUser;
    //             let value = this.step(board,depth - 1,this.exchangeAIOrUser(aiOrUser));
    //             if(value < best){
    //                 best = value;
    //             }
    //             cell.value = 0;
    //         });
    //         return best;
    //     }else{
    //         // 取最大值
    //         if(depth < 1){
    //             return this.evaluate(this.ai_patterns,board);
    //         }
    //
    //         let best = -Infinity;
    //         emptyCells.forEach(cell=>{
    //             cell.value = aiOrUser;
    //             let value = this.step(board,depth - 1,this.exchangeAIOrUser(aiOrUser));
    //             if(value > best){
    //                 best = value;
    //             }
    //             cell.value = 0;
    //         });
    //         return best;
    //     }
    // },


    // exchangeAIOrUser(v){
    //     if(v === this.Role.User){
    //         return this.Role.AI;
    //     }
    //     return this.Role.User;
    // },

    getCellScore(patterns,board,cell){
        let cells = board.cells;

        // 横着
        let row = cells[cell.rowIdx];
        let minColIdx = clamp(cell.colIdx - 4,0,Size - 1);
        let maxColIdx = clamp(cell.colIdx + 4,0,Size - 1);
        let charArr = [];
        for(let j = minColIdx; j <= maxColIdx; ++j){
            charArr.push(row[j].value);
        }
        let rowStr = charArr.join('');


        // 竖着
        let minRowIdx = clamp(cell.rowIdx - 4,0,Size - 1);
        let maxRowIdx = clamp(cell.rowIdx + 4,0,Size - 1);
        charArr.length = 0;
        for(let i = minRowIdx; i <= maxRowIdx;++i){
            charArr.push(cells[i][cell.colIdx].value);
        }
        let colStr = charArr.join('');

        //  \
        // 直接先计算所有的,再循环剔除掉越界的
        charArr.length = 0;
        for(let k = 0; k < 9;++k){
            let r = cell.rowIdx - 4 + k;
            let c = cell.colIdx - 4 + k;
            if( r >=0 && r < Size && c >= 0 && c < Size){
                charArr.push(cells[r][c].value);
            }
        }
        let fxStr = charArr.join('');

        // /
        charArr.length = 0;
        for(let k = 0;k < 9; ++k){
            let r = cell.rowIdx + 4 - k;
            let c = cell.colIdx - 4 + k;
            if( r >=0 && r < Size && c >= 0 && c < Size){
                charArr.push(cells[r][c].value);
            }
        }
        let xStr = charArr.join('');

        // 计算 得分
        return this._callScore(patterns,[rowStr,colStr,fxStr,xStr]);
    },

    /**
     * 最整个棋盘进行评估
     * @param board
     * @return {*|number}
     */
    evaluate(patterns,board){
        let cells = board.cells;
        let sum = 0;
        cells.forEach(row=>{
            row.forEach(cell=>{
                if(cell.value !== 0){
                    return;
                }
                sum += this.getCellScore(patterns,board,cell);
            });
        });
        return sum;
    },

    _callScore(patterns,strArr){
        let sum = 0;
        strArr.forEach(str=>{
            let score = 0;
            for(let i = 0,len = patterns.length; i < len; ++i){
                let p = patterns[i];
                let key = p.key;
                if(key.test(str)){
                    score = p.value;
                    break;
                }
            }
            sum += score;
        });
        return sum;
    }
};
